package com.insight.modules.system.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yuanqiao.insight.acore.depart.entity.SysDepart;
import com.insight.common.api.vo.Result;
import com.insight.common.system.vo.LoginUser;
import com.insight.common.system.vo.SysUserCacheInfo;
import com.insight.modules.system.entity.SysUsers;
import com.insight.modules.system.model.SysUserSysDepartModel;
import com.insight.modules.system.vo.UserVo;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 用户表 服务类
 * </p>
 *
 * @Author scott
 * @since 2018-12-20
 */
public interface ISysUserService extends IService<SysUsers> {

    /**
     * 重置用户密码
     *
     * @param username        用户名
     * @param oldpassword     旧密码
     * @param newpassword     新密码
     * @param confirmpassword 确认新密码
     * @return 处理结果
     */
    public Result<?> resetPassword(String username, String oldpassword, String newpassword, String confirmpassword);

    /**
     * 修改用户密码
     *
     * @param sysUser 用户实体，包含新密码等信息
     * @return 处理结果
     */
    public Result<?> changePassword(SysUsers sysUser);

    /**
     * 删除用户
     *
     * @param userId 用户ID
     * @return 是否删除成功
     */
    public boolean deleteUser(String userId);

    /**
     * 批量删除用户
     *
     * @param userIds 逗号分隔的用户ID字符串
     * @return 是否删除成功
     */
    public boolean deleteBatchUsers(String userIds);

    /**
     * 根据用户名查询用户实体
     *
     * @param username 用户名
     * @return 用户实体
     */
    public SysUsers getUserByName(String username);

    /**
     * 添加用户并设置用户角色关系
     *
     * @param user  用户实体
     * @param roles 角色ID字符串，逗号分隔
     */
    public void addUserWithRole(SysUsers user, String roles);

    /**
     * 编辑用户并更新用户角色关系
     *
     * @param user  用户实体
     * @param roles 角色ID字符串，逗号分隔
     */
    public void editUserWithRole(SysUsers user, String roles);

    /**
     * 获取指定用户名的角色编码列表
     *
     * @param username 用户名
     * @return 角色编码列表
     */
    public List<String> getRole(String username);

    /**
     * 查询用户信息及所属部门信息缓存
     *
     * @param username 用户名
     * @return 用户缓存信息（包含部门等）
     */
    public SysUserCacheInfo getCacheUser(String username);

    /**
     * 根据部门ID分页查询用户列表
     *
     * @param page     分页对象
     * @param departId 部门ID
     * @param username 用户名筛选条件
     * @return 分页用户列表
     */
    public IPage<SysUsers> getUserByDepId(Page<SysUsers> page, String departId, String username);

    /**
     * 根据多个部门ID分页查询用户列表
     *
     * @param page      分页对象
     * @param departIds 部门ID列表
     * @param username  用户名筛选条件
     * @return 分页用户列表
     */
    public IPage<SysUsers> getUserByDepIds(Page<SysUsers> page, List<String> departIds, String username);

    /**
     * 根据部门ID查询用户列表（不分页）
     *
     * @param departId 部门ID
     * @return 用户列表
     */
    public List<SysUsers> getUserByDepId(String departId);

    /**
     * 根据用户ID集合获取对应的部门名称，多个部门名称逗号分隔
     *
     * @param userIds 用户ID集合
     * @return key=用户ID, value=所属部门名称字符串
     */
    public Map<String, String> getDepNamesByUserIds(List<String> userIds);

    /**
     * 根据部门ID和自定义查询条件分页查询用户列表
     *
     * @param page         分页对象
     * @param departId     部门ID
     * @param queryWrapper 查询条件包装器
     * @return 分页用户列表
     */
    public IPage<SysUsers> getUserByDepartIdAndQueryWrapper(Page<SysUsers> page, String departId, QueryWrapper<SysUsers> queryWrapper);

    /**
     * 根据部门编码查询部门及其子部门下的用户，支持分页
     *
     * @param orgCode    部门编码
     * @param userParams 用户查询条件，可为空
     * @param page       分页参数
     * @return 分页用户及部门信息模型
     */
    IPage<SysUserSysDepartModel> queryUserByOrgCode(String orgCode, SysUsers userParams, IPage page);

    /**
     * 根据角色ID分页查询用户列表
     *
     * @param page     分页对象
     * @param roleId   角色ID
     * @param username 用户名筛选条件
     * @param realname 真实姓名筛选条件
     * @return 分页用户列表
     */
    public IPage<SysUsers> getUserByRoleId(Page<SysUsers> page, String roleId, String username, String realname);

    /**
     * 根据用户名获取该用户所有角色编码集合
     *
     * @param username 用户名
     * @return 角色编码集合
     */
    Set<String> getUserRolesSet(String username);

    /**
     * 根据用户名获取该用户所有权限编码集合
     *
     * @param username 用户名
     * @return 权限编码集合
     */
    Set<String> getUserPermissionsSet(String username);

    /**
     * 根据用户名更新该用户的部门编码
     *
     * @param username 用户名
     * @param orgCode  部门编码
     */
    void updateUserDepart(String username, String orgCode);

    /**
     * 根据手机号查询用户信息
     *
     * @param phone 手机号
     * @return 用户实体
     */
    public SysUsers getUserByPhone(String phone);

    /**
     * 根据邮箱查询用户信息
     *
     * @param email 邮箱地址
     * @return 用户实体
     */
    public SysUsers getUserByEmail(String email);

    /**
     * 添加用户及其部门关联关系
     *
     * @param user          用户实体
     * @param selectedParts 部门ID字符串，逗号分隔
     */
    void addUserWithDepart(SysUsers user, String selectedParts);

    /**
     * 编辑用户及其部门关联关系
     *
     * @param user    用户实体
     * @param departs 部门ID字符串，逗号分隔
     */
    void editUserWithDepart(SysUsers user, String departs);

    /**
     * 校验用户是否有效（激活状态、账号状态等）
     *
     * @param sysUser 用户实体
     * @return 校验结果及相关信息
     */
    Result<JSONObject> checkUserIsEffective(SysUsers sysUser);

    /**
     * 查询所有被逻辑删除的用户
     *
     * @return 被逻辑删除的用户列表
     */
    List<SysUsers> queryLogicDeleted();

    /**
     * 根据条件查询被逻辑删除的用户
     *
     * @param wrapper 条件查询包装器
     * @return 被逻辑删除的用户列表
     */
    List<SysUsers> queryLogicDeleted(LambdaQueryWrapper<SysUsers> wrapper);

    /**
     * 还原逻辑删除的用户
     *
     * @param userIds      用户ID列表
     * @param updateEntity 更新实体（用于覆盖字段）
     * @return 是否成功
     */
    boolean revertLogicDeleted(List<String> userIds, SysUsers updateEntity);

    /**
     * 彻底删除逻辑删除的用户
     *
     * @param userIds 用户ID列表
     * @return 是否成功
     */
    boolean removeLogicDeleted(List<String> userIds);

    /**
     * 将手机号和邮箱中空字符串更新为 null
     *
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    boolean updateNullPhoneEmail();

    /**
     * 保存第三方登录用户信息
     *
     * @param sysUser 用户实体
     */
    void saveThirdUser(SysUsers sysUser);

    /**
     * 根据多个部门ID和用户名模糊查询用户列表
     *
     * @param departIds 部门ID列表
     * @param username  用户名模糊查询条件
     * @return 用户列表
     */
    List<SysUsers> queryByDepIds(List<String> departIds, String username);

    /**
     * 查询所有用户的ID和姓名映射
     *
     * @return 用户ID-姓名映射
     */
    Map<String, String> getUserMap();

    /**
     * 查询所有用户ID和姓名映射（可能用于特殊场景）
     *
     * @return 用户ID-姓名映射
     */
    Map<String, String> getUserIdAndNmaeMap();

    /**
     * 查询所有用户列表
     *
     * @return 用户列表
     */
    List<SysUsers> getList();

    /**
     * 通过账号获取用户登录信息
     *
     * @param loginName 账号
     * @return 登录用户信息
     */
    LoginUser getUsersByLoginUser(String loginName);

    /**
     * 根据用户名查询真实姓名
     *
     * @param ownerId 用户名
     * @return 真实姓名
     */
    String selectRealnameByUsername(String ownerId);

    /**
     * 查询所有用户名与真实姓名映射
     *
     * @return 映射表
     */
    Map<String, String> selectRealnameByUsername();

    /**
     * 获取用户ID，可能用于验证或转换
     *
     * @param userid 用户ID
     * @return 用户ID
     */
    String getUserid(String userid);

    /**
     * 根据部门信息添加用户
     *
     * @param sysDepart 部门实体
     */
    void addUserByDepart(SysDepart sysDepart);

    /**
     * 根据用户ID查询用户实体
     *
     * @param s 用户ID
     * @return 用户实体
     */
    SysUsers getByUId(String s);

    /**
     * 根据用户名获取用户实体（特定查询）
     *
     * @param s 用户名
     * @return 用户实体
     */
    SysUsers getUserByNameSpec(String s);

    /**
     * 根据用户ID列表批量查询用户实体
     *
     * @param sentTo 用户ID列表
     * @return 用户列表
     */
    List<SysUsers> getUserByIds(List<String> sentTo);

    /**
     * 同步单个用户信息
     *
     * @param user JSON格式的用户信息
     * @return 受影响条数
     */
    int syncUser(cn.hutool.json.JSONObject user);

    /**
     * 根据组织机构编码查询用户视图列表
     *
     * @param org 组织机构编码
     * @return 用户视图列表
     */
    List<UserVo> list(String org);

    /**
     * 批量同步组织机构用户信息
     *
     * @param sysUsers 用户实体列表
     */
    void syncZJGUser(List<SysUsers> sysUsers);

    /**
     * 同步中银用户信息
     *
     * @param user    用户JSONArray数据
     * @param isFirst 是否第一次同步
     */
    void syncZyUser(JSONArray user, boolean isFirst);

    /**
     * 查询指定前缀的号码列表
     *
     * @param prefix 前缀字符串
     * @return 号码字符串列表
     */
    List<String> selectNumbers(String prefix);

    /**
     * 根据用户名删除用户信息（物理删除）
     *
     * @param userId 用户名
     */
    void deleteUserByuserName(String userId);

    /**
     * 批量根据用户名删除用户信息
     *
     * @param userIds 用户名列表
     */
    void deleteUserByuserNames(List<String> userIds);

    /**
     * 直接删除用户及其关联数据（物理删除）
     *
     * @param userIds 用户ID列表
     * @return 是否删除成功
     */
    boolean deleteDirectly(List<String> userIds);

    /**
     * 根据条件分页查询用户及其部门ID
     *
     * @param page    分页对象
     * @param sysUser 用户查询条件实体
     * @return 分页用户列表，包含部门ID
     */
    IPage<SysUsers> getUsersWithDeptIds(Page<SysUsers> page, SysUsers sysUser);
}
